import { computed, nextTick, reactive } from 'vue';
import * as XLSX from 'xlsx';
import { saveAs } from 'file-saver';
import to from 'await-to-js';

export default () => {
  const state = reactive({
    // 接口服务
    service: null as any,
    // column
    column: [] as any[],
    // excel生成所需数组
    list: [] as any[],
    // 接口调用额外参数
    otherParams: {},
    // 分片单次数量
    limit: 100,
    // 当前分片页数
    page: 1,
    // 数据总量
    total: -1,
    //按钮菊花
    xlsxLoading:false,
    // 任务进行中(wait:等待任务;doing:任务进行中;done:任务完成;)
    running: 'wait',
     // 任务成功与否
     isSuccess: true,
  })

  // 进度
  const progress = computed(() => {
    return (state.total === -1 || state.total === 0) ? 0 : Number((state.page / Math.ceil(state.total / state.limit) * 100).toFixed(0));
  })

  // 初始化生成任务
  const init = (config?: { limit?: number, otherParams?: any, service?: any}) => {
    state.otherParams = config?.otherParams || {};
    state.column = [];
    state.list = [];
    state.total = -1;
    state.page = 1;
    state.service = config?.service || null;
    config?.limit && (state.limit = config.limit);
    state.running = 'wait';
    state.isSuccess = true;
  }

  // 调用接口生成
  const defineList = async (arr: any[]) => {
    state.column = arr;
    if (state.total === -1 || state.list.length < state.total) {
      state.running = 'doing';
      const [err, res]: any = await to(state.service?.({ page: state.page, limit: state.limit, ...state.otherParams }));
      if (!err) {
        state.total = res.data?.total || 0;
        res?.data?.data?.forEach((x: any) => {
          let obj: any = {};
          arr.forEach((y: any) => {
            if (y.value instanceof Array) {
              let val: any = null;
              y.value.forEach((z: any) => {
                val = val ? val[z] : x[z];
              })
              obj[y.label] = val;
            } else {
              obj[y.label] = x[y.value];
            }
          })
          state.list.push(obj);
        })
        state.page++;
        await defineList(arr);
      }else {
        state.isSuccess = false;
      }
    }
  }
  // 开始生成任务
  const exportToExcel = async (fileName: string) => {
    if(!state.isSuccess) {
      state.running = 'done';
      return;
    }
    const wb = XLSX.utils.book_new();
    const ws = XLSX.utils.json_to_sheet(state.list);
    const wscols = state.column.map((x: any) => {
      return {
        wch: x.width || 20,
      }
    });
    ws["!cols"] = wscols;
    XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
    const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
    const s2ab = (s: any) => {
      const buf = new ArrayBuffer(s.length);
      const view = new Uint8Array(buf);
      for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
      return buf;
    }

    // 保存文件
    saveAs(new Blob([s2ab(wbout)], { type: 'application/octet-stream' }), fileName);
    state.running = 'done';
  }

  return {
    state,
    progress,
    init,
    defineList,
    exportToExcel,
  }
}